﻿#ifndef _RTSP_COMMON_H_INCLUDE_
#define _RTSP_COMMON_H_INCLUDE_

#include <memory>
#include <QString>
#include <QSize>
#include <QList>

#include <WinSock2.h>

#if defined ( __cplusplus)
extern "C"
{
#include "libx264/x264.h"
#include "libswscale/swscale.h"
#include "libavutil/imgutils.h"
};
#else
#include "x264.h"
#endif

#pragma comment(lib,"ws2_32.lib")

#define USER_AGENT "-_-"

class CRtspClient;

struct RtspUrlInfo
{
    QString url;
    QString ip;
    quint16 port;
    QString suffix;
};

enum Method
{
    OPTIONS=0,
    DESCRIBE,
    ANNOUNCE,
    RECORD,
    SETUP,
    PLAY,
    TEARDOWN,
    GET_PARAMETER,
    RTCP,
    MNONE,
};

typedef struct _RTP_header
{
    /* 小端序 */
    unsigned char csrc      : 4;
    unsigned char extension : 1;
    unsigned char padding   : 1;
    unsigned char version   : 2;
    unsigned char payload   : 7;
    unsigned char marker    : 1;

    unsigned short seq;
    unsigned int   ts;
    unsigned int   ssrc;
} RtpHeader;

#define RTP_HEADER_SIZE   	   12
#define MAX_RTP_PAYLOAD_SIZE   1420 //1460  1500-20-12-8
#define RTP_VERSION			   2
#define RTP_TCP_HEAD_SIZE	   4
#define RTP_VPX_HEAD_SIZE	   1

/* RTSP服务支持的媒体类型 */
enum MediaType
{
    //PCMU = 0,
    PCMA = 8,
    H264 = 96,
    AAC  = 37,
    H265 = 265,
    NONE
};

enum FrameType
{
    VIDEO_FRAME_I = 0x01,
    VIDEO_FRAME_P = 0x02,
    VIDEO_FRAME_B = 0x03,
    AUDIO_FRAME   = 0x11,
};

enum MediaChannelId
{
    channel_0,
    channel_1
};

struct AVFrame
{
    AVFrame(unsigned int size = 0)
        :buffer(new unsigned char[size + 1], std::default_delete< unsigned char[]>())
    {
        this->size = size;
        type = 0;
        timestamp = 0;
    }

    std::shared_ptr<unsigned char> buffer;    /* 帧数据 */
    unsigned int size;				          /* 帧大小 */
    unsigned char type;				          /* 帧类型 */
    unsigned int timestamp;		  	          /* 时间戳 */
};

struct RtpPacket
{
    RtpPacket()
        : data(new unsigned char[1600], std::default_delete<unsigned char[]>())
    {
        type = 0;
        size = 0;
        timestamp = 0;
        last = 0;
    }

    std::shared_ptr<unsigned char> data;
    unsigned int size;
    unsigned int timestamp;
    unsigned char  type;
    unsigned char  last;
};

struct tagPacket
{
    unsigned char  type;
    unsigned char  last;
    unsigned char  size1;
    unsigned char  size2;
};

enum ConnectionMode
{
    RTSP_SERVER,
    RTSP_PUSHER,
    RTSP_CLIENT
};

struct RtspGroup
{
    RtspGroup()
        : pusher(NULL) {}

    CRtspClient *pusher;
    QList<CRtspClient*> clients;
};

static int m_iNal = 0;
static x264_nal_t* m_Nals = NULL;
static x264_t* m_Handle = NULL;
static x264_picture_t* m_Pic_in= NULL;
static x264_picture_t* m_Pic_out= NULL;
static x264_param_t* m_Param= NULL;
static struct SwsContext * m_SwsContext=NULL;
static uint8_t *src_data[4];
static int src_linesize[4];
static int m_baseFrameSize = 0;
static QSize m_contextSize;
static AVPixelFormat m_srcFormat=AV_PIX_FMT_RGB24;

#endif
